Correct CVE-2017-922[4-9] Fix mutilple invalid pointer dereference, out-of-bounds write memory corruption and stack buffer overflow, Origin: Cheerypicked from upstream Bug: https://github.com/kkos/oniguruma/issues/[55|56|57|58|59|60] Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=86331[2|3|4|5|6|8] Forwarded: not-needed Last-Update: 2017-05-25 --- This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ Index: 6.1.3-1+deb9u1/src/regexec.c =================================================================== --- 6.1.3-1+deb9u1.orig/src/regexec.c +++ 6.1.3-1+deb9u1/src/regexec.c @@ -1463,14 +1463,9 @@ match_at(regex_t* reg, const UChar* str, break; case OP_EXACT1: MOP_IN(OP_EXACT1); -#if 0 DATA_ENSURE(1); if (*p != *s) goto fail; p++; s++; -#endif - if (*p != *s++) goto fail; - DATA_ENSURE(0); - p++; MOP_OUT; break; @@ -3149,6 +3144,8 @@ forward_search_range(regex_t* reg, const } else { UChar *q = p + reg->dmin; + + if (q >= end) return 0; /* fail */ while (p < q) p += enclen(reg->enc, p); } } @@ -3228,18 +3225,25 @@ forward_search_range(regex_t* reg, const } else { if (reg->dmax != ONIG_INFINITE_DISTANCE) { - *low = p - reg->dmax; - if (*low > s) { - *low = onigenc_get_right_adjust_char_head_with_prev(reg->enc, s, - *low, (const UChar** )low_prev); - if (low_prev && IS_NULL(*low_prev)) - *low_prev = onigenc_get_prev_char_head(reg->enc, - (pprev ? pprev : s), *low); - } - else { + if (p - str < reg->dmax) { + *low = (UChar* )str; if (low_prev) - *low_prev = onigenc_get_prev_char_head(reg->enc, - (pprev ? pprev : str), *low); + *low_prev = onigenc_get_prev_char_head(reg->enc, str, *low); + } + else { + *low = p - reg->dmax; + if (*low > s) { + *low = onigenc_get_right_adjust_char_head_with_prev(reg->enc, s, + *low, (const UChar** )low_prev); + if (low_prev && IS_NULL(*low_prev)) + *low_prev = onigenc_get_prev_char_head(reg->enc, + (pprev ? pprev : s), *low); + } + else { + if (low_prev) + *low_prev = onigenc_get_prev_char_head(reg->enc, + (pprev ? pprev : str), *low); + } } } } Index: 6.1.3-1+deb9u1/src/regparse.c =================================================================== --- 6.1.3-1+deb9u1.orig/src/regparse.c +++ 6.1.3-1+deb9u1/src/regparse.c @@ -2986,7 +2986,7 @@ fetch_token_in_cc(OnigToken* tok, UChar* PUNFETCH; prev = p; num = scan_unsigned_octal_number(&p, end, 3, enc); - if (num < 0) return ONIGERR_TOO_BIG_NUMBER; + if (num < 0 || num >= 256) return ONIGERR_TOO_BIG_NUMBER; if (p == prev) { /* can't read nothing. */ num = 0; /* but, it's not error */ } @@ -3358,7 +3358,7 @@ fetch_token(OnigToken* tok, UChar** src, if (IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_OCTAL3)) { prev = p; num = scan_unsigned_octal_number(&p, end, (c == '0' ? 2:3), enc); - if (num < 0) return ONIGERR_TOO_BIG_NUMBER; + if (num < 0 || num >= 256) return ONIGERR_TOO_BIG_NUMBER; if (p == prev) { /* can't read nothing. */ num = 0; /* but, it's not error */ } @@ -3994,7 +3994,9 @@ next_state_class(CClassNode* cc, OnigCod } } - *state = CCS_VALUE; + if (*state != CCS_START) + *state = CCS_VALUE; + *type = CCV_CLASS; return 0; } @@ -4010,6 +4012,9 @@ next_state_val(CClassNode* cc, OnigCodeP switch (*state) { case CCS_VALUE: if (*type == CCV_SB) { + if (*vs > 0xff) + return ONIGERR_INVALID_CODE_POINT_VALUE; + BITSET_SET_BIT(cc->bs, (int )(*vs)); } else if (*type == CCV_CODE_POINT) { Index: 6.1.3-1+deb9u1/src/gperf_unfold_key_conv.py =================================================================== --- 6.1.3-1+deb9u1.orig/src/gperf_unfold_key_conv.py +++ 6.1.3-1+deb9u1/src/gperf_unfold_key_conv.py @@ -36,7 +36,7 @@ def parse_line(s): if r != s: return r r = re.sub(REG_GET_CODE, 'OnigCodePoint gcode = wordlist[key].code;', s) if r != s: return r - r = re.sub(REG_CODE_CHECK, 'if (code == gcode)', s) + r = re.sub(REG_CODE_CHECK, 'if (code == gcode && wordlist[key].index >= 0)', s) if r != s: return r return s Index: 6.1.3-1+deb9u1/src/unicode_unfold_key.c =================================================================== --- 6.1.3-1+deb9u1.orig/src/unicode_unfold_key.c +++ 6.1.3-1+deb9u1/src/unicode_unfold_key.c @@ -2844,7 +2844,7 @@ unicode_unfold_key(OnigCodePoint code) { OnigCodePoint gcode = wordlist[key].code; - if (code == gcode) + if (code == gcode && wordlist[key].index >= 0) return &wordlist[key]; } }